package com.zzy.common.config;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zzy.common.entity.db.AdminDaoEntity;
import com.zzy.module.admin.mapper.AdminMapper;
import com.zzy.module.admin.mapper.PermissionMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Set;

/**
 * @author zhuZhaoYang
 * @date 2021/7/12 9:17
 */
@Component
public class UserRealm extends AuthorizingRealm {

    private final Logger logger = LoggerFactory.getLogger(UserRealm.class);

    private PermissionMapper permissionMapper;
    private AdminMapper adminMapper;

    @Autowired
    public void setPermissionMapper(PermissionMapper permissionMapper) {
        this.permissionMapper = permissionMapper;
    }

    @Autowired
    public void setAdminUserMapper(AdminMapper adminMapper) {
        this.adminMapper = adminMapper;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        logger.debug("开始配置权限列表......");
        AdminDaoEntity user = (AdminDaoEntity) principals.getPrimaryPrincipal();
        Set<String> permsSet = permissionMapper.getAllPermissionByActorId(user.getActorType());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(permsSet);
        logger.debug("权限列表:" + permsSet);
        return info;
    }


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        //查询用户信息
        AdminDaoEntity user = adminMapper.selectOne(
                new QueryWrapper<AdminDaoEntity>().eq(AdminDaoEntity.TableFiledConst.USERNAME,
                        token.getUsername()));
        //不是管理员
        if (user == null) {
            throw new AuthenticationException("账号不存在");
        }

        DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
        DefaultWebSessionManager sessionManager = (DefaultWebSessionManager) securityManager.getSessionManager();
        //获取当前已登录的用户session列表
        Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();
        for (Session session : sessions) {
            //判断用是否登录
            SimplePrincipalCollection simplePrincipalCollection = (SimplePrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
            if (simplePrincipalCollection != null) {
                AdminDaoEntity adminDaoEntity = (AdminDaoEntity) simplePrincipalCollection.getPrimaryPrincipal();
                if (adminDaoEntity.getUsername().equals(user.getUsername())) {
                    sessionManager.getSessionDAO().delete(session);
                }
            }
        }

        //设置加密 1次
        return new SimpleAuthenticationInfo(user, user.getPassword()
                , ByteSource.Util.bytes(user.getSalt()), getName());
    }

    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
        shaCredentialsMatcher.setHashAlgorithmName("md5");
        shaCredentialsMatcher.setHashIterations(1);
        super.setCredentialsMatcher(shaCredentialsMatcher);
    }


}
